%{

(* verilog grammer 

------ From: Chris Satterlee, Wed, May 3, 1995 ------
Verilog Formal Syntax Specification
The basis for this formal syntax specification was obtained from the home page of Professor Don Thomas, who obtained it from the Verilog Language Reference Manual, Version 2.0, available from Open Verilog International (OVI) and is used with their permission.

The specification printed here is edited somewhat based on the ongoing Verilog standardization process which is being carried out by the IEEE 1364 Working Group. Thus, the specification printed here may be partially inaccurate. The result of this standardization process may be obtained from the IEEE or from OVI, whose offices are at 15466 Los Gatos Blvd, Suite 109071, Los Gatos, CA 95032 (408) 353-8899.

This .html file was generated by Chris Satterlee who has allowed us to make it available to you. This is the same BNF that was distributed with the first and second edition of the book (pre-IEEE-standardization). Try it out with your favorite net surfer. For more information, contact:

Chris Satterlee
RAS System Level Design Engineer
Silicon Graphics Computer Systems
Mountain View, CA
csatt@sgi.com

     1. Source Text
     2. Declarations
     3. Primitive Instances
     4. Module  Instantiations
     5. Behavioral Statements
     6. Specify Section
     7. Expressions
     8. General 


Definition of Items in Formal Syntax Specifications:
+-----------------------+------------------------------------------------------------+
|      Item            |               Meaning                                     |
+-----------------------+------------------------------------------------------------+
| White space           | may be used to separate lexical tokens                     |
+-----------------------+------------------------------------------------------------+
| Angle brackets        | surround each description item and are not literal sym-    |
|                       | bols. That is, they do not appear in the source descrip-   |
|                       | tion. Any text outside angle brackets is literal.          |
+-----------------------+------------------------------------------------------------+
| <name> in lower case  | is a syntax construct item                                 |
+-----------------------+------------------------------------------------------------+
| <NAME> in upper case  | is a lexical token item. Its definition is a terminal node |
|                       | in the description hierarchy -- that is, its definition    |
|                       | does not contain any syntax construct items                |
+-----------------------+------------------------------------------------------------+
| <name>?               | is an optional item                                        |
+-----------------------+------------------------------------------------------------+
| <name>*               | is zero, one, or more items                                |
+-----------------------+------------------------------------------------------------+
| <name>+               | is one or more items                                       |
+-----------------------+------------------------------------------------------------+
| <name><,<name>>*      | is a comma-separated list of items with at least one       |
|                       | item in the list                                           |
+-----------------------+------------------------------------------------------------+
| <name>::=             | gives a syntax definition to an item                       |
+-----------------------+------------------------------------------------------------+
| ||=                   | introduces an alternative syntax definition                |
+-----------------------+------------------------------------------------------------+


1. Source Text

<source_text>
	::= <description>*

<description>
	::= <module>
	||= <UDP>

<module>
	::= module <name_of_module> <list_of_ports>? ;
		<module_item>*
		endmodule
	||= macromodule <name_of_module> <list_of_ports>? ;
		<module_item>*
		endmodule

<name_of_module>
	::= <IDENTIFIER>

<list_of_ports>
	::= ( <port> <,<port>>* )

<port>
	::= <port_expression>?
	||= . <name_of_port> ( <port_expression>? )

<port_expression>
	::= <port_reference>
	||= { <port_reference> <,<port_reference>>* }

<port_reference>
	::= <name_of_variable>
	||= <name_of_variable> [ <constant_expression> ]
	||= <name_of_variable> [ <constant_expression> :<constant_expression> ]

<name_of_port>
	::= <IDENTIFIER>

<name_of_variable>
	::= <IDENTIFIER>

<module_item>
	::= <parameter_declaration>
	||= <input_declaration>
	||= <output_declaration>
	||= <inout_declaration>
	||= <net_declaration>
	||= <reg_declaration>
	||= <time_declaration>
	||= <integer_declaration>
	||= <real_declaration>
	||= <event_declaration>
	||= <gate_declaration>
	||= <UDP_instantiation>
	||= <module_instantiation>
	||= <parameter_override>
	||= <continuous_assign>
	||= <specify_block>
	||= <initial_statement>
	||= <always_statement>
	||= <task>
	||= <function>

<UDP>
	::= primitive <name_of_UDP> ( <name_of_variable>
		<,<name_of_variable>>* ) ;
		<UDP_declaration>+
		<UDP_initial_statement>?
		<table_definition>
		endprimitive

<name_of_UDP>
	::= <IDENTIFIER>

<UDP_declaration>
	::= <output_declaration>
	||= <reg_declaration>
	||= <input_declaration>

<UDP_initial_statement>
	::= initial <output_terminal_name> = <init_val> ;

<init_val>
	::= 1'b0
	||= 1'b1
	||= 1'bx
	||= 1'bX
	||= 1'B0
	||= 1'B1
	||= 1'Bx
	||= 1'BX
	||= 1
	||= 0

<output_terminal_name>
	::= <name_of_variable>

<table_definition>
	::= table <table_entries> endtable

<table_entries>
	::= <combinational_entry>+
	||= <sequential_entry>+

<combinational_entry>
	::= <level_input_list> : <OUTPUT_SYMBOL> ;

<sequential_entry>
	::= <input_list> : <state> : <next_state> ;

<input_list>
	::= <level_input_list>
	||= <edge_input_list>

<level_input_list>
	::= <LEVEL_SYMBOL>+

<edge_input_list>
	::= <LEVEL_SYMBOL>* <edge> <LEVEL_SYMBOL>*

<edge>
	::= ( <LEVEL_SYMBOL> <LEVEL_SYMBOL> )
	||= <EDGE_SYMBOL>

<state>
	::= <LEVEL_SYMBOL>

<next_state>
	::= <OUTPUT_SYMBOL>
	||= - (This is a literal hyphen, see Chapter 5 for details).

<OUTPUT_SYMBOL> is one of the following characters:
	0   1   x   X

<LEVEL_SYMBOL> is one of the following characters:
	0   1   x   X   ?   b   B

<EDGE_SYMBOL> is one of the following characters:
	r   R   f   F   p   P   n   N   *


<task>
	::= task <name_of_task> ;
		<tf_declaration>*
		<statement_or_null>
		endtask

<name_of_task>
	::= <IDENTIFIER>

<function>
	::= function <range_or_type>? <name_of_function> ;
		<tf_declaration>+
		<statement>
		endfunction

<range_or_type>
	::= <range>
	||= integer
	||= real

<name_of_function>
	::= <IDENTIFIER>

<tf_declaration>
	::= <parameter_declaration>
	||= <input_declaration>
	||= <output_declaration>
	||= <inout_declaration>
	||= <reg_declaration>
	||= <time_declaration>
	||= <integer_declaration>
	||= <real_declaration>


2. Declarations

<parameter_declaration>
	::= parameter <list_of_param_assignments> ;

<list_of_param_assignments>
	::=<param_assignment><,<param_assignment>*

<param_assignment>
	::=<identifier> = <constant_expression>

<input_declaration>
	::= input <range>? <list_of_variables> ;

<output_declaration>
	::= output <range>? <list_of_variables> ;

<inout_declaration>
	::= inout <range>? <list_of_variables> ;

<net_declaration>
	::= <NETTYPE> <expandrange>? <delay>? <list_of_variables> ;
	||= trireg <charge_strength>? <expandrange>? <delay>?

<list_of_variables> ;
	||= <NETTYPE> <drive_strength>? <expandrange>? <delay>? <list_of_assignments> ;

<NETTYPE> is one of the following keywords:
	wire  tri  tri1  supply0  wand  triand  tri0  supply1  wor  trior  trireg

<expandrange>
	::= <range>
	||= scalared <range>
	||= vectored <range>

<reg_declaration>
	::= reg <range>? <list_of_register_variables> ;

<time_declaration>
	::= time <list_of_register_variables> ;

<integer_declaration>
	::= integer <list_of_register_variables> ;

<real_declaration>
	::= real <list_of_variables> ;

<event_declaration>
	::= event <name_of_event> <,<name_of_event>>* ;

<continuous_assign>
	::= assign <drive_strength>? <delay>? <list_of_assignments> ;
	||= <NETTYPE> <drive_strength>? <expandrange>? <delay>? <list_of_assignments> ;

<parameter_override>
	::= defparam <list_of_param_assignments> ;

<list_of_variables>
	::= <name_of_variable> <,<name_of_variable>>*

<name_of_variable>
	::= <IDENTIFIER>

<list_of_register_variables>
	::= <register_variable> <,<register_variable>>*

<register_variable>
	::= <name_of_register>
	||= <name_of_memory> [ <constant_expression> : <constant_expression> ]

<name_of_register>
	::= <IDENTIFIER>

<name_of_memory>
	::= <IDENTIFIER>

<name_of_event>
	::= <IDENTIFIER>

<charge_strength>
	::= ( small )
	||= ( medium )
	||= ( large )

<drive_strength>
	::= ( <STRENGTH0> , <STRENGTH1> )
	||= ( <STRENGTH1> , <STRENGTH0> )

<STRENGTH0> is one of the following keywords:
	supply0  strong0  pull0  weak0  highz0

<STRENGTH1> is one of the following keywords:
	supply1  strong1  pull1  weak1  highz1

<range>
	::= [ <constant_expression> : <constant_expression> ]

<list_of_assignments>
	::= <assignment> <,<assignment>>*



3. Primitive Instances

<gate_declaration>
	::= <GATETYPE> <drive_strength>? <delay>?  <gate_instance> <,<gate_instance>>* ;

<GATETYPE> is one of the following keywords:
	and  nand  or  nor xor  xnor buf  bufif0 bufif1  not  notif0 notif1  pulldown pullup
	nmos  rnmos pmos rpmos cmos rcmos   tran rtran  tranif0  rtranif0  tranif1 rtranif1

<delay>
	::= # <number>
	||= # <identifier>
	||= # (<mintypmax_expression> <,<mintypmax_expression>>? <,<mintypmax_expression>>?)

<gate_instance>
	::= <name_of_gate_instance>? ( <terminal> <,<terminal>>* )

<name_of_gate_instance>
	::= <IDENTIFIER><range>?

<UDP_instantiation>
	::= <name_of_UDP> <drive_strength>? <delay>?
	<UDP_instance> <,<UDP_instance>>* ;

<name_of_UDP>
	::= <IDENTIFIER>

<UDP_instance>
	::= <name_of_UDP_instance>? ( <terminal> <,<terminal>>* )

<name_of_UDP_instance>
	::= <IDENTIFIER><range>?

<terminal>
	::= <expression>
	||= <IDENTIFIER>


4. Module Instantiations

<module_instantiation>
	::= <name_of_module> <parameter_value_assignment>?
		<module_instance> <,<module_instance>>* ;

<name_of_module>
	::= <IDENTIFIER>

<parameter_value_assignment>
	::= # ( <expression> <,<expression>>* )

<module_instance>
	::= <name_of_instance> ( <list_of_module_connections>? )

<name_of_instance>
	::= <IDENTIFIER><range>?

<list_of_module_connections>
	::= <module_port_connection> <,<module_port_connection>>*
	||= <named_port_connection> <,<named_port_connection>>*

<module_port_connection>
	::= <expression>
	||= <NULL>

<NULL>
	::= nothing - this form covers the case of an empty item in a list - for example:
	      (a, b, , d)

<named_port_connection>
	::= .< IDENTIFIER> ( <expression> )



5. Behavioral Statements

<initial_statement>
	::= initial <statement>

<always_statement>
	::= always <statement>

<statement_or_null>
	::= <statement>
	||= ;

<statement>
	::=<blocking_assignment> ;
	||= <non_blocking_assignment> ;
	||= if ( <expression> ) <statement_or_null>
	||= if ( <expression> ) <statement_or_null> else <statement_or_null>
	||= case ( <expression> ) <case_item>+ endcase
	||= casez ( <expression> ) <case_item>+ endcase
	||= casex ( <expression> ) <case_item>+ endcase
	||= forever <statement>
	||= repeat ( <expression> ) <statement>
	||= while ( <expression> ) <statement>
	||= for ( <assignment> ; <expression> ; <assignment> ) <statement>
	||= <delay_or_event_control> <statement_or_null>
	||= wait ( <expression> ) <statement_or_null>
	||= -> <name_of_event> ;
	||= <seq_block>
	||= <par_block>
	||= <task_enable>
	||= <system_task_enable>
	||= disable <name_of_task> ;
	||= disable <name_of_block> ;
	||= assign <assignment> ;
	||= deassign <lvalue> ;
	||= force <assignment> ;
	||= release <lvalue> ;

<assignment>
	::= <lvalue> = <expression>

<blocking_assignment>
	::= <lvalue> = <expression>
	||= <lvalue> = <delay_or_event_control> <expression> ;

<non_blocking_assignment>
	::= <lvalue> <= <expression>
	||= <lvalue> = <delay_or_event_control> <expression> ;

<delay_or_event_control>
	::= <delay_control>
	||= <event_control>
	||= repeat ( <expression> ) <event_control>

<case_item>
	::= <expression> <,<expression>>* : <statement_or_null>
	||= default : <statement_or_null>
	||= default <statement_or_null>

<seq_block>
	::= begin <statement>* end
	||= begin : <name_of_block> <block_declaration>* <statement>* end

<par_block>
	::= fork <statement>* join
	||= fork : <name_of_block> <block_declaration>* <statement>* join

<name_of_block>
	::= <IDENTIFIER>

<block_declaration>
	::= <parameter_declaration>
	||= <reg_declaration>
	||= <integer_declaration>
	||= <real_declaration>
	||= <time_declaration>
	||= <event_declaration>

<task_enable>
	::= <name_of_task>
	||= <name_of_task> ( <expression> <,<expression>>* ) ;

<system_task_enable>
	::= <name_of_system_task> ;
	||= <name_of_system_task> ( <expression> <,<expression>>* ) ;

<name_of_system_task>
	::= $<system_identifier> (Note: the $ may not be followed by a space.)

<SYSTEM_IDENTIFIER>
	An <IDENTIFIER> assigned to an existing system task or function



6. Specify Section

<specify_block>
	::= specify <specify_item>* endspecify

<specify_item>
	::= <specparam_declaration>
	||= <path_declaration>
	||= <level_sensitive_path_declaration>
	||= <edge_sensitive_path_declaration>
	||= <system_timing_check>
	||= <sdpd>

<specparam_declaration>
	::= specparam <list_of_param_assignments> ;

<list_of_param_assignments>
	::=<param_assignment><,<param_assignment>>*

<param_assignment>
	::=<<identifier>=<constant_expression>>

<path_declaration>
	::= <path_description> = <path_delay_value> ;

<path_description>
	::= ( <specify_input_terminal_descriptor> => <specify_output_terminal_descriptor> )
	||= ( <list_of_path_inputs> *> <list_of_path_outputs> )

<list_of_path_inputs>
	::= <specify_input_terminal_descriptor> <,<specify_input_terminal_descriptor>>*

<list_of_path_outputs>
	::=  <specify_output_terminal_descriptor> <,<specify_output_terminal_descriptor>>*

<specify_input_terminal_descriptor>
	::= <input_identifier>
	||= <input_identifier> [ <constant_expression> ]
	||= <input_identifier> [ <constant_expression> : <constant_expression> ]

<specify_output_terminal_descriptor>
	::= <output_identifier>
	||= <output_identifier> [ <constant_expression> ]
	||= <output_identifier> [ <constant_expression> : <constant_expression> ]

<input_identifier>
	::= the <IDENTIFIER> of a module input or inout terminal

<output_identifier>
	::= the <IDENTIFIER> of a module output or inout terminal.

<path_delay_value>
	::= <path_delay_expression>
	||= ( <path_delay_expression>, <path_delay_expression> )
	||= ( <path_delay_expression>, <path_delay_expression>,
		<path_delay_expression>)
	||= ( <path_delay_expression>, <path_delay_expression>,
		<path_delay_expression>, <path_delay_expression>,
		<path_delay_expression>, <path_delay_expression> )
	||= ( <path_delay_expression>, <path_delay_expression>,
		<path_delay_expression>, <path_delay_expression>,
		<path_delay_expression>, <path_delay_expression>,
		<path_delay_expression>, <path_delay_expression>,
		<path_delay_expression>, <path_delay_expression>,
		<path_delay_expression>, <path_delay_expression> )

<path_delay_expression>
	::= <mintypmax_expression>

<system_timing_check>
	::= $setup( <timing_check_event>, <timing_check_event>,
		<timing_check_limit>
		<,<notify_register>>? ) ;
	||= $hold( <timing_check_event>, <timing_check_event>,
		<timing_check_limit>
		<,<notify_register>>? ) ;
	||= $period( <controlled_timing_check_event>, <timing_check_limit>
		<,<notify_register>>? ) ;
	||= $width( <controlled_timing_check_event>, <timing_check_limit>
		<,<constant_expression>,<notify_register>>? ) ;
	||= $skew( <timing_check_event>, <timing_check_event>,
		<timing_check_limit>
		<,<notify_register>>? ) ;
	||= $recovery( <controlled_timing_check_event>,
		<timing_check_event>,
		<timing_check_limit> <,<notify_register>>? ) ;
	||= $setuphold( <timing_check_event>, <timing_check_event>,
		<timing_check_limit>, <timing_check_limit> <,<notify_register>>? ) ;

<timing_check_event>
	::= <timing_check_event_control>? <specify_terminal_descriptor>
		<&&& <timing_check_condition>>?

<specify_terminal_descriptor>
	::= <specify_input_terminal_descriptor>
	||=<specify_output_terminal_descriptor>

<controlled_timing_check_event>
	::= <timing_check_event_control> <specify_terminal_descriptor>
		<&&&  <timing_check_condition>>?

<timing_check_event_control>
	::= posedge
	||= negedge
	||= <edge_control_specifier>

<edge_control_specifier>
	::= edge  [ <edge_descriptor><,<edge_descriptor>>*]

<edge_descriptor>
	::= 01
	||= 10
	||= 0x
	||= x1
	||= 1x
	||= x0

<timing_check_condition>
	::= <scalar_timing_check_condition>
	||= ( <scalar_timing_check_condition> )

<scalar_timing_check_condition>
	::= <scalar_expression>
	||= ~<scalar_expression>
	||= <scalar_expression> == <scalar_constant>
	||= <scalar_expression> === <scalar_constant>
	||= <scalar_expression> != <scalar_constant>
	||= <scalar_expression> !== <scalar_constant>

<scalar_expression>
	A scalar expression is a one bit net or a bit-select of an expanded vector net.

<timing_check_limit>
	::= <expression>

<scalar_constant>
	::= 1'b0
	||= 1'b1
	||= 1'B0
	||= 1'B1
	||= 'b0
	||= 'b1
	||= 'B0
	||= 'B1
	||= 1
	||= 0

<notify_register>
	::= <identifier>

<level_sensitive_path_declaration>
	::= if (<conditional_port_expression>)
		(<specify_input_terminal_descriptor> <polarity_operator>? =>
		<specify_output_terminal_descriptor>) = <path_delay_value>;
	||= if (<conditional_port_expression>)
		(<list_of_path_inputs> <polarity_operator>? *>
		<list_of_path_outputs>) = <path_delay_value>;
	(Note: The following two symbols are literal symbols, not syntax description conventions:)
		*>	=>

<conditional_port_expression>
	::= <port_reference>
	||= <UNARY_OPERATOR><port_reference>
	||= <port_reference><BINARY_OPERATOR><port_reference>

<polarity_operator>
	::= +
	||= -

<edge_sensitive_path_declaration>
	::= <if (<expression>)>? (<edge_identifier>?
		<specify_input_terminal_descriptor> =>
		(<specify_output_terminal_descriptor> <polarity_operator>?
		: <data_source_expression>)) = <path_delay_value>;
	||= <if (<expression>)>? (<edge_identifier>?
		<specify_input_terminal_descriptor> *>
		(<list_of_path_outputs> <polarity_operator>?
		: <data_source_expression>)) =<path_delay_value>;

<data_source_expression>
	Any expression, including constants and lists. Its width must be one bit or
	equal to the  destination's width. If the destination is a list, the data
	source must be as wide as the sum of  the bits of the members.

<edge_identifier>
	::= posedge
	||= negedge

<sdpd>
	::=if(<sdpd_conditional_expression>)<path_description>=<path_delay_value>;

<sdpd_conditional_expresssion>
	::=<expression><BINARY_OPERATOR><expression>
	||=<UNARY_OPERATOR><expression>


7. Expressions

<lvalue>
	::= <identifier>
	||= <identifier> [ <expression> ]
	||= <identifier> [ <constant_expression> : <constant_expression> ]
	||= <concatenation>

<constant_expression>
	::=<expression>

<mintypmax_expression>
	::= <expression>
	||= <expression> : <expression> : <expression>

<expression>
	::= <primary>
	||= <UNARY_OPERATOR> <primary>
	||= <expression> <BINARY_OPERATOR> <expression>
	||= <expression> <QUESTION_MARK> <expression> : <expression>
	||= <STRING>


<UNARY_OPERATOR> is one of the following tokens:
	+  -  !  ~  &  ~&  |  ^|  ^  ~^

<BINARY_OPERATOR> is one of the following tokens:
	+  -  *  /  %  ==  !=  ===  !==  &&  ||  <  <=  >  >=  &  |  ^  ^~  >>  <<

<QUESTION_MARK> is ? (a literal question mark).

<STRING> is text enclosed in "" and contained on one line.

<primary>
	::= <number>
	||= <identifier>
	||= <identifier> [ <expression> ]
	||= <identifier> [ <constant_expression> : <constant_expression> ]
	||= <concatenation>
	||= <multiple_concatenation>
	||= <function_call>
	||= ( <mintypmax_expression> )

<number>
	::= <DECIMAL_NUMBER>
	||= <UNSIGNED_NUMBER>? <BASE> <UNSIGNED_NUMBER>
	||= <DECIMAL_NUMBER>.<UNSIGNED_NUMBER>
	||= <DECIMAL_NUMBER><.<UNSIGNED_NUMBER>>?
		E<DECIMAL_NUMBER>
	||= <DECIMAL_NUMBER><.<UNSIGNED_NUMBER>>?
		e<DECIMAL_NUMBER>
	(Note: embedded spaces are illegal in Verilog numbers, but embedded underscore
	characters can be used for spacing in any type of number.)

<DECIMAL_NUMBER>
	::= A number containing a set of any of the following characters, optionally preceded by + or -
	 	0123456789_

<UNSIGNED_NUMBER>
	::= A number containing a set of any of the following characters:
	        0123456789_

<NUMBER>
	Numbers can be specified in decimal, hexadecimal, octal or binary, and may
	optionally start with a + or -.  The <BASE> token controls what number digits
	are legal.  <BASE> must be one of d, h, o, or b, for the bases decimal,
	hexadecimal, octal, and binary respectively. A number can contain any set of
	the following characters that is consistent with <BASE>:
	0123456789abcdefABCDEFxXzZ?

<BASE> is one of the following tokens:
	'b   'B   'o   'O   'd   'D   'h   'H

<concatenation>
	::= { <expression> <,<expression>>* }

<multiple_concatenation>
	::= { <expression> { <expression> <,<expression>>* } }

<function_call>
	::= <name_of_function> ( <expression> <,<expression>>* )
	||= <name_of_system_function> ( <expression> <,<expression>>* )
	||= <name_of_system_function>

<name_of_function>
	::= <identifier>

<name_of_system_function>
	::= $<SYSTEM_IDENTIFIER>
	(Note: the $ may not be followed by a space.)




8. General

<comment>
	::= <short_comment>
	||= <long_comment>

<short_comment>
	::= // <comment_text> <END-OF-LINE>

<long_comment>
	::= /* <comment_text> */

<comment_text>
	::= The comment text is zero or more ASCII characters

<identifier>
	::= <IDENTIFIER><.<IDENTIFIER>>*
	(Note: the period may not be preceded or followed by a space.)

<IDENTIFIER>
	An identifier is any sequence of letters, digits, dollar signs ($), and
	underscore (_) symbol, except that the first must be a letter or the
	underscore; the first character may not be a digit or $. Upper and lower case
	letters are considered to be different. Identifiers may be up to 1024
	characters long. Some Verilog-based tools do not recognize  identifier
	characters beyond the 1024th as a significant part of the identifier. Escaped
	identifiers start with the backslash character (\) and may include any
	printable ASCII character. An escaped identifier ends with white space. The
	leading backslash character is not considered to be part of the identifier.

<delay>
	::= # <number>
	||= # <identifier>
	||= # ( <mintypmax_expression> <,<mintypmax_expression>>?
		<,<mintypmax_expression>>?)

<delay_control>
	::= # <number>
	||= # <identifier>
	||= # ( <mintypmax_expression> )

<event_control>
	::= @ <identifier>
	||= @ ( <event_expression> )

<event_expression>
	::= <expression>
	||= posedge <scalar_event_expression>
	||= negedge <scalar_event_expression>
	||= <event_expression> or <event_expression>

<scalar_event_expression>
	Scalar event expression is an expression that resolves to a one bit value.

*)

type module_t = string 
type ident_t = string list
type base_t = BaseBinary | BaseOctal | BaseDecimal | BaseHex | BaseFloat
type number_t = base_t * string
type hdl_t = 
    | Module of module_t
    | MacroModule
    | Udp

%}

%token T_module
%token T_macromodule
%token T_endmodule
%token T_udp
%token <string> T_ident
%token <string> T_system_ident
%token <number_t> T_number
%token <base_t> T_base
%token T_semi
%token T_comma
%token T_colon
%token T_question_mark
%token T_dot
%token T_ob
%token T_cb
%token T_ocb
%token T_ccb
%token T_osb
%token T_csb
%token T_add
%token T_sub
%token T_mul
%token T_div
%token T_hat
%token T_not
%token T_exclam
%token T_and
%token T_or
%token T_mod
%token T_eq
%token T_less
%token T_great
%token <string> T_string

%token T_endfile

%start source_text
%type <hdl_t list> source_text

%% 

source_text:
    description_list { $1 }

description_list:
    { [] }
  | description description_list { $1 :: $2 }

description:
	p_module { $1 }
  | udp { $1 }

p_module: 
    T_module name_of_module opt_list_of_ports T_semi module_items T_endmodule { Module($2) }
  | T_macromodule name_of_module opt_list_of_ports T_semi module_items T_endmodule { MacroModule }

udp: 
    T_udp { Udp }

name_of_module: 
    T_ident { $1 }

opt_list_of_ports:
    { [] }
  | T_ob comma_ports T_cb { $2 }

comma_ports:
    port { [$1] }
  | port T_comma comma_ports { $1 :: $3 }

port:
    {}
  | port_expression {} 
  | T_dot name_of_port T_ob port_expression T_cb {}

port_expression:
    port_reference {}
  | T_ocb port_reference_list T_ccb {}

port_reference_list:
    port_reference { [$1] }
  | port_reference T_comma port_reference_list { $1 :: $3 }

port_reference:
    name_of_variable { $1 }
  | name_of_variable T_osb constant_expression T_csb { $1 }
  | name_of_variable T_osb constant_expression T_colon constant_expression T_csb { $1 }

name_of_port:
    T_ident { $1 }

name_of_variable:
    T_ident { $1 }

module_items:
    { [] }

module_item:
    parameter_declaration {}
  | input_declaration {}
  | output_declaration {}
  | inout_declaration {}
  | net_declaration {}
  | reg_declaration {}
  | time_declaration {}
  | integer_declaration {}
  | real_declaration {}
  | event_declaration {}
  | gate_declaration {}
  | UDP_instantiation {}
  | module_instantiation {}
  | parameter_override {}
  | continuous_assign {}
  | specify_block {}
  | initial_statement {}
  | always_statement {}
  | task {}
  | function {}

UDP
	::= primitive <name_of_UDP> ( <name_of_variable>
		<,<name_of_variable>>* ) ;
		<UDP_declaration>+
		<UDP_initial_statement>?
		<table_definition>
		endprimitive

<name_of_UDP>
	::= <IDENTIFIER>

<UDP_declaration>
	::= <output_declaration>
	||= <reg_declaration>
	||= <input_declaration>

<UDP_initial_statement>
	::= initial <output_terminal_name> = <init_val> ;

<init_val>
	::= 1'b0
	||= 1'b1
	||= 1'bx
	||= 1'bX
	||= 1'B0
	||= 1'B1
	||= 1'Bx
	||= 1'BX
	||= 1
	||= 0

<output_terminal_name>
	::= <name_of_variable>

<table_definition>
	::= table <table_entries> endtable

<table_entries>
	::= <combinational_entry>+
	||= <sequential_entry>+

<combinational_entry>
	::= <level_input_list> : <OUTPUT_SYMBOL> ;

<sequential_entry>
	::= <input_list> : <state> : <next_state> ;

<input_list>
	::= <level_input_list>
	||= <edge_input_list>

<level_input_list>
	::= <LEVEL_SYMBOL>+

<edge_input_list>
	::= <LEVEL_SYMBOL>* <edge> <LEVEL_SYMBOL>*

<edge>
	::= ( <LEVEL_SYMBOL> <LEVEL_SYMBOL> )
	||= <EDGE_SYMBOL>

<state>
	::= <LEVEL_SYMBOL>

<next_state>
	::= <OUTPUT_SYMBOL>
	||= - (This is a literal hyphen, see Chapter 5 for details).

<OUTPUT_SYMBOL> is one of the following characters:
	0   1   x   X

<LEVEL_SYMBOL> is one of the following characters:
	0   1   x   X   ?   b   B

<EDGE_SYMBOL> is one of the following characters:
	r   R   f   F   p   P   n   N   *


<task>
	::= task <name_of_task> ;
		<tf_declaration>*
		<statement_or_null>
		endtask

<name_of_task>
	::= <IDENTIFIER>

<function>
	::= function <range_or_type>? <name_of_function> ;
		<tf_declaration>+
		<statement>
		endfunction

<range_or_type>
	::= <range>
	||= integer
	||= real

<name_of_function>
	::= <IDENTIFIER>

<tf_declaration>
	::= <parameter_declaration>
	||= <input_declaration>
	||= <output_declaration>
	||= <inout_declaration>
	||= <reg_declaration>
	||= <time_declaration>
	||= <integer_declaration>
	||= <real_declaration>


/*************************************** EXPRESSIONS ****************************************/

lvalue:
    identifier {}
  | identifier T_osb expression T_csb {}
  | identifier T_osb constant_expression T_colon constant_expression T_csb {}
  | concatenation {}

constant_expression:
    expression {}

mintypmax_expression:
    expression {}
  | expression T_colon expression T_colon expression {}

expression:
    primary {}
  | unary_operator primary {}
  | expression binary_operator expression {}
  | expression T_question_mark expression T_colon expression {}
  | string {}

unary_operator:
    T_add {}
  | T_sub {}
  | T_exclam {}
  | T_not {}
  | T_and {}
  | T_not T_and {}
  | T_or {}
  | T_hat T_or {}
  | T_hat {}
  | T_not T_hat {}

binary_operator:
    T_add {}
  | T_sub {}
  | T_mul {}
  | T_div {}
  | T_mod {}
  | T_eq T_eq {}
  | T_exclam T_eq {}
  | T_eq T_eq T_eq {}
  | T_exclam T_eq T_eq {}
  | T_and T_and {}
  | T_or T_or {}
  | T_less {}
  | T_less T_eq {}
  | T_great  {}
  | T_great T_eq {}
  | T_and {}
  | T_or {}
  | T_hat {}
  | T_hat T_not {}
  | T_great T_great {}
  | T_less T_less {}

string: 
    T_string { $1 }

concatenation:
    T_ocb concatenation_list T_ccb {}

concatenation_list:
    expression { [$1] }
  | expression T_comma concatenation_list { $1 :: $3 }

multiple_concatenation:
	T_ocb expression concatenation T_ccb {}

primary:
    number {}
  | identifier {}
  | identifier T_osb expression T_csb {}
  | identifier T_osb constant_expression T_colon constant_expression T_csb {}
  | concatenation {}
  | multiple_concatenation {}
  | function_call {} 
  | T_ob mintypmax_expression T_cb {}

number:
    T_number { $1 }

function_call:
    name_of_function T_ob expression_comma_list T_cb {}
  | name_of_system_function T_ob expression_comma_list T_cb {}
  | name_of_system_function {}

expression_comma_list:
    expression { }
  | expression T_comma expression_comma_list { }

name_of_function:
	T_ident { $1 }

name_of_system_function:
	T_system_ident { $1 }

/*************************************** GENERAL ****************************************/

identifier:
    T_ident { [$1] }
  | T_ident T_dot identifier { $1 :: $3 }




